#include <stdio.h>

#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"

#include "hi_io.h"
#include "hi_pwm.h"
#include "hi_gpio.h"

#define DELAY_10MS 10*1000
#define DELAY_100MS 100*1000
#define DELAY_1S 1*1000*1000

#define SPEAKER_PORT HI_GPIO_IDX_9
#define KEY4_PORT    HI_GPIO_IDX_8

uint16_t timer_count = 0;
uint8_t key4_flag = 0;

/**
 * @brief function to respond the interrupt of key pressing
 * 
 * @param arg NULL
 */
static void KEY4_Isr(char *arg)
{
    (void)arg;

    if(key4_flag == 0)
        key4_flag = 1;
}

/**
 * @brief User GPIO initialization 
 */
static void User_GPIO_Init(void)
{
    /** GPIO initialization **/
    hi_gpio_init();
    
    /** Set pin 9 function to GPIO **/
    hi_io_set_func(SPEAKER_PORT, HI_IO_FUNC_GPIO_9_GPIO);
    /** Set GPIO 09 direction to output **/
    hi_gpio_set_dir(SPEAKER_PORT, HI_GPIO_DIR_OUT);
    /** Set GPIO 09 output to Low **/
    hi_gpio_set_ouput_val(SPEAKER_PORT, 0);

    /** Set pin 8 function to GPIO **/
    hi_io_set_func(KEY4_PORT, HI_IO_FUNC_GPIO_8_GPIO);
    /** Set pin 8 to Pull Up**/
    hi_io_set_pull(KEY4_PORT,HI_IO_PULL_UP);
    /** Set GPIO 08 direction to input **/
    hi_gpio_set_dir(KEY4_PORT, HI_GPIO_DIR_IN);
    /** Set GPIO 08 Schmitt Trigger **/
    hi_io_set_schmitt(KEY4_PORT, 1);
    /** Set GPIO 08 interrupt **/
    hi_gpio_register_isr_function(KEY4_PORT, HI_INT_TYPE_EDGE, HI_GPIO_EDGE_FALL_LEVEL_LOW,
                                    KEY4_Isr, NULL);
}

/**
 * @brief function to respond key pressing
 */
static int8_t KEY4_Halrd(void)
{
    if(key4_flag == 1){
        /** Debound **/
        usleep(DELAY_100MS);
        key4_flag = 0;

        return 0;
    }
    else 
        return -1;
}

/**
 * @brief function to manage timer
 * 
 * @param arg NULL
 */
static void Timer_Halrd(char *arg)
{
    (void)arg;
    timer_count++;
}

static void *TIMERTask(const char *arg)
{
    (void)arg;

    osTimerId_t tid;
    uint8_t count = 0;
    /** User GPIO initialization  **/
    User_GPIO_Init();
    /** Create a timer **/
    tid = osTimerNew(Timer_Halrd,
                        osTimerPeriodic,
                        NULL,
                        NULL);
    /** Start the timer, tick is 100 system ticks (default 10ms) **/
    osTimerStart(tid, 100);
    while(1)
    {
        if(timer_count == 20){
            /** Set GPIO09 output to High **/
            hi_gpio_set_ouput_val(SPEAKER_PORT, 1);
        }
        if(timer_count == 25){
            timer_count = 0;
            /** Set GPIO09 output to Low **/
            hi_gpio_set_ouput_val(SPEAKER_PORT, 0);
        }
        /** Once key is pressed, shut the buzzer **/
        if( KEY4_Halrd() == 0){
            /** Set GPIO09 output to Low **/
            hi_gpio_set_ouput_val(SPEAKER_PORT, 0);
        }
        if(++count == 100){
            count = 0;
            printf("timer_count:%d\n", timer_count);
        }
        usleep(DELAY_10MS);
    }

    return NULL;
}

static void TIMERTaskEntry(void)
{
    osThreadAttr_t attr;

    attr.name = "TIMERTask";        
    attr.attr_bits = 0U;            
    attr.cb_mem = NULL;             
    attr.cb_size = 0U;              
    attr.stack_mem = NULL;          
    attr.stack_size = 4096;         
    attr.priority = 11;             

    if (osThreadNew((osThreadFunc_t)TIMERTask, NULL, &attr) == NULL) {
        printf("[TIMERTaskEntry] Failed to create TIMERTask!\n");
    }
}

SYS_RUN(TIMERTaskEntry);
